package com.nebula.service.Impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nebula.common.Const;
import com.nebula.common.ServerResponse;
import com.nebula.mapper.FilesMapper;
import com.nebula.mapper.FoldersMapper;
import com.nebula.pojo.Files;
import com.nebula.pojo.User;
import com.nebula.service.IFileService;
import com.nebula.util.FileUtil;
import com.nebula.util.PageUtil;
import com.nebula.vo.FileListVo;

@Service("fileService")
public class FileServiceImpl implements IFileService {
	@Autowired
	private FilesMapper filesMapper;
	
	public List<FileListVo> pictureList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> filesList = filesMapper.selectPictureList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : filesList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVo.setFileShortUrl(Const.VIRTUAL_DIRECTORY + fileListVo.getFileShortUrl());
			System.out.println("short_url：" + fileListVo.getFileShortUrl());
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(filesList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public List<FileListVo> documentList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> filesList = filesMapper.selectDocumentList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : filesList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(filesList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public List<FileListVo> videoList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> fileList = filesMapper.selectVideoList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : fileList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(fileList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public List<FileListVo> seedsList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> fileList = filesMapper.selectSeedsList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : fileList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(fileList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public List<FileListVo> musicList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> fileList = filesMapper.selectMusicList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : fileList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(fileList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public List<FileListVo> otherList(int pageNum,int pageSize,String username,HttpServletRequest request){
		PageHelper.startPage(pageNum, pageSize);
		List<Files> fileList = filesMapper.selectOtherList(username);
		List<FileListVo> fileListVos = Lists.newArrayList();
		for(Files files : fileList){
			FileListVo fileListVo = assembleFileListVo(files);
			fileListVos.add(fileListVo);
		}
		
		PageInfo<Files> pageInfo = new PageInfo<Files>(fileList);
		Map<String, Object> map = PageUtil.pageInfo(pageInfo);
		request.setAttribute("pageInfo", map);
		return fileListVos;
	}
	
	public ServerResponse<String> rename(Files files){
		if(files != null && files.getFileid() != null){
			int resultCount = filesMapper.updateByPrimaryKeySelective(files);
			if(resultCount > 0){
				return ServerResponse.createBySuccessMessage("修改文件名成功");
			}
			return ServerResponse.createByErrorMessage("修改文件名失败");
		}
		return ServerResponse.createByErrorMessage("更新文件参数不正确");
	}
	
	public void download(HttpServletRequest requset,HttpServletResponse response,long fileId){
		Files files = filesMapper.selectByPrimaryKey(fileId);
		File file = new File(files.getFileStoragePath());
		String filename = files.getFileRealName()+"."+files.getFileExtension();
		InputStream inputStream = null;
		ServletOutputStream outputStream = null;
		if(file.exists()){
			try {
				filename = new String(filename.getBytes("UTF-8"),"iso-8859-1");
				response.setContentType("application/x-msdownload");
				response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
				response.setContentLengthLong(file.length());
				inputStream = new FileInputStream(file);
				outputStream = response.getOutputStream();
				byte[] b = new byte[1024];
				int i = 0;
				while((i = inputStream.read(b)) != -1){
					outputStream.write(b,0,i);
				}
			}catch (IOException e) {
				e.printStackTrace();
			}finally {
				try {
					outputStream.close();
					outputStream.flush();
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public void plDownload(HttpServletRequest requset,HttpServletResponse response,String zipname,String ctm,User user) throws IOException{
		String name = zipname.substring(0,zipname.lastIndexOf(".") - 1);
		String src = requset.getSession().getServletContext().getRealPath("tempZip/" + user.getUsername() + "/" 
				+ ctm);
		File file = new File(src + "/" + name + "/" + zipname);
		InputStream inputStream = null;
		ServletOutputStream outputStream = null;
		if(file.exists()){
			try {
				zipname = new String(("【批量下载】" + zipname).getBytes("utf-8"),"iso-8859-1");
				response.setContentType("application/x-msdownload");
				response.setHeader("Content-Disposition", "attachment;filename=\"" + zipname + "\"");
				response.setContentLengthLong(file.length());
				inputStream = new FileInputStream(file);
				outputStream = response.getOutputStream();
				int len = 0;
				byte []b = new byte[1024];
				while((len = inputStream.read(b)) != -1){
					outputStream.write(b, 0, len);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if(outputStream != null){
					outputStream.flush();
					outputStream.close();
				}
				if(inputStream != null){
					inputStream.close();
				}
			}
		}
	}
	
	public ServerResponse compress(HttpServletRequest requset,HttpServletResponse response
			,String fileIdGroup,User user) throws IOException{
		String []str = fileIdGroup.split(",");
		List<Files> list = Lists.newArrayList();
		String rt = "\r\n\r\n";
		for(int i = 0,len=str.length;i<len;i++){
			Files files = filesMapper.selectByPrimaryKey(Long.parseLong(str[i]));
			list.add(files);
		}
		if(!list.isEmpty()){
			String zipname = list.get(0).getFileRealName()+"等.zip";
			
			long ctm = System.currentTimeMillis();
			//临时文件夹存放压缩包
			String tempPath = requset.getSession().getServletContext().getRealPath("tempZip/" + user.getUsername()
			+ "/" + ctm + "/" + list.get(0).getFileRealName());
			File tempZipDir = new File(tempPath);
			if(!tempZipDir.exists()){
				tempZipDir.mkdirs();
				tempZipDir.setWritable(true);
			}
			
			File tempZip = new File(tempPath,zipname);
			
			zipname = new String(zipname.getBytes("utf-8"),"iso-8859-1");
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tempZip));
			for(Files files : list){
				String filename = files.getFileRealName()+"."+files.getFileExtension();
				File file = new File(files.getFileStoragePath());
				ZipEntry zipEntry = new ZipEntry(filename);
				zos.putNextEntry(zipEntry);
				FileInputStream fis = new FileInputStream(file);
				byte []b = new byte[1024];
				int len = 0;
				while((len = fis.read(b)) != -1){
					zos.write(b, 0, len);
				}
				zos.flush();
				fis.close();
			}
			zos.setEncoding("utf-8");
			zos.setComment("Thank you for using the tai ling shan secondary school net disk system.");
			zos.flush();
			zos.close();
			Map<String , String> map = Maps.newHashMap();
			map.put("ctm", String.valueOf(ctm));
			map.put("zipname", new String(zipname.getBytes("iso-8859-1"),"utf-8"));
			try {
				Thread.sleep(1500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return ServerResponse.createBySuccess(map);
		}
		return ServerResponse.createByErrorMessage("打包失败");
	}
	
	public int getFileCount(long fileid){
		int resultCount = filesMapper.selectFileCountByPrimaryKey(fileid);
		if(resultCount > 0){
			return resultCount;
		}
		return 0;
	}
	
	public ServerResponse getShortUrlByFileId(Long fileid){
		Files files = filesMapper.selectByPrimaryKey(fileid);
		if(files != null){
			return ServerResponse.createBySuccess(files.getFileShortUrl());
		}
		return ServerResponse.createByErrorMessage("参数错误,请检查参数");
	}
	
	private FileListVo assembleFileListVo(Files files){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		
		String []imgTypes = {"jpg","jpeg","gif","png","bmp","ico"};
		String []musicTypes = {"mp3","wav","wma","flac","ape","aac","ogg"};
		String []zipTypes = {"rar","zip","7z","iso","cab","arj","jar","rar5"};
		String []vedioTypes = {"avi","wmv","mpeg","mp4","mov","mkv","flv","f4v","m4v","rmvb",
				"rm","3gp","dat","ts","mts","vob"};
		String []notRead = {"exe","torrent","apk","flac","ape","vsd"};
		
		FileListVo fileListVo = new FileListVo();
		
		fileListVo.setFileid(files.getFileid());
		fileListVo.setFileRealName(files.getFileRealName()+"."+files.getFileExtension());
		fileListVo.setFileSize(FileUtil.byteCountToDisplaySize(files.getFileSize()));
		fileListVo.setUpdatedtime(sdf.format(files.getUpdatedtime()));
		fileListVo.setFileExtension(files.getFileExtension());
		fileListVo.setFileShortUrl(files.getFileShortUrl());
		
		String lowercaseSuffix = files.getFileExtension().toLowerCase().trim();
		
		//图片
		for(String type : imgTypes){
			if(lowercaseSuffix.indexOf(type) > -1){
				fileListVo.setIcon(Const.IMG_ICON);
				break;
			}
		}
				
		//音乐
		for(String type : musicTypes){
			if(lowercaseSuffix.indexOf(type) > -1){
				fileListVo.setIcon(Const.MUSIC_ICON);
				break;
			}
		}
				
		//压缩文件
		for(String type : zipTypes){
			if(lowercaseSuffix.indexOf(type) > -1){
				fileListVo.setIcon(Const.ZIP_ICON);
				break;
			}
		}
				
		//视频文件
		for(String type : vedioTypes){
			if(lowercaseSuffix.indexOf(type) > -1){
				fileListVo.setIcon(Const.VEDIO_ICON);
				break;
			}
		}
		
		if(fileListVo.getIcon() == null || fileListVo.getIcon().equals("")){
			if("apk".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.APK_ICON);
			}
			else if("torrent".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.BT_ICON);
			}
			else if("pdf".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.PDF_ICON);
			}
			else if("xls".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.XLS_ICON);
			}
			else if("txt".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.TXT_ICON);
			}
			else if("exe".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.EXE_ICON);
			}
			else if("folder".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.FOLDER_ICON);
			}
			else if("doc".equals(lowercaseSuffix) || "docx".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.DOC_ICON);
			}
			else if("ppt".equals(lowercaseSuffix) || "pptx".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.PPT_ICON);
			}
			else if("vsd".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.VSD_ICON);
			}else if("html".equals(lowercaseSuffix)){
				fileListVo.setIcon(Const.HTML_ICON);
			}
			else {
				fileListVo.setIcon(Const.UNKNOWN_ICON);
			}
		}
		return fileListVo;
	}
	
	/*private byte[] httpConverBytes(String path){
		BufferedInputStream bis = null;
		ByteArrayOutputStream baos = null;
		URLConnection urlConn = null;
		
		try {
			URL url = new URL(path);
			urlConn = url.openConnection();
			
			bis = new BufferedInputStream(urlConn.getInputStream());
			
			baos = new ByteArrayOutputStream(1024);
			byte[] b = new byte[1024];
			int i = 0;
			if((i = bis.read(b)) != -1){
				baos.write(b,0,i);
			}
			return baos.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bis.close();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}*/
}
